"use strict";
/**
 * @ Author: Yoann Meclot. MSay2
 * @ Created on: 2020-07-13 08:20:15
 * @ Modified on: 2021-06-14 17:57:05
 */
/**
 * Copyright (c) 2020-2021 MSay2 (Yoann Meclot) - @msay2/tspoet
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) {
    if (!privateMap.has(receiver)) {
        throw new TypeError("attempted to set private field on non-instance");
    }
    privateMap.set(receiver, value);
    return value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) {
    if (!privateMap.has(receiver)) {
        throw new TypeError("attempted to get private field on non-instance");
    }
    return privateMap.get(receiver);
};
var _mValues, _mIndex, _mSize, _mValues_1, _mLength;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ArrayList = void 0;
const Argument_js_1 = require("../Argument.js");
const Exceptions_js_1 = require("../Exceptions.js");
const StringBuilder_js_1 = require("../StringBuilder.js");
const Utils_js_1 = require("../Utils.js");
const Arrays_js_1 = require("./Arrays.js");
const List_js_1 = require("./List.js");
/**
 * The EntryIterable class is a mean to reiterate the entries to the array.
 *
 * It allows to you obtain eachs values of eachs entries of the array
 * with its respectives methods Entry.getValue.
 *
 * @class EntryIterable
 * @implements {Iterable}
 * @version 1.2
 * @since 1.5
 */
class EntryIterable {
    constructor(values, size) {
        _mValues.set(this, []);
        _mIndex.set(this, -1);
        _mSize.set(this, 0);
        __classPrivateFieldSet(this, _mValues, values);
        __classPrivateFieldSet(this, _mSize, size);
    }
    [(_mValues = new WeakMap(), _mIndex = new WeakMap(), _mSize = new WeakMap(), Symbol.iterator)]() {
        return {
            next: () => {
                __classPrivateFieldSet(this, _mIndex, +__classPrivateFieldGet(this, _mIndex) + 1);
                if (__classPrivateFieldGet(this, _mIndex) < __classPrivateFieldGet(this, _mSize)) {
                    return {
                        value: {
                            getValue: () => __classPrivateFieldGet(this, _mValues)[__classPrivateFieldGet(this, _mIndex)],
                            index: () => __classPrivateFieldGet(this, _mIndex),
                            isLastData: () => {
                                if (__classPrivateFieldGet(this, _mIndex) == __classPrivateFieldGet(this, _mSize) - 1)
                                    return true;
                                return false;
                            },
                            isFirstData: () => {
                                if (__classPrivateFieldGet(this, _mIndex) == 0)
                                    return true;
                                return false;
                            }
                        },
                        done: false
                    };
                }
                return {
                    value: null,
                    done: true
                };
            }
        };
    }
}
class ArrayList extends List_js_1.List {
    constructor(array) {
        super();
        _mValues_1.set(this, []);
        _mLength.set(this, 0);
        if (array != undefined && array != null) {
            __classPrivateFieldSet(this, _mValues_1, array);
            __classPrivateFieldSet(this, _mLength, array.length);
        }
    }
    add(value) {
        __classPrivateFieldGet(this, _mValues_1)[__classPrivateFieldGet(this, _mLength)] = value;
        this.ensureIncrementSize(1);
    }
    addAt(index, value) {
        let otherValues = [];
        for (let i = 0, v = 0, e = 0; i < __classPrivateFieldGet(this, _mLength) + 1; i++) {
            if (i == index)
                otherValues[v++] = value;
            else
                otherValues[v++] = __classPrivateFieldGet(this, _mValues_1)[e++];
        }
        this.ensureIncrementSize(1);
        __classPrivateFieldSet(this, _mValues_1, otherValues);
        otherValues = null;
    }
    addAll(...lists) {
        for (let list of lists) {
            if (!Argument_js_1.Argument.isOf(list, "ArrayList"))
                throw new Exceptions_js_1.ObjectCastException(`ArrayList: ${list.constructor.name} is not an instance of ArrayList.`);
            let size = list.size();
            if (size > 0)
                for (let entry of list.entries())
                    this.add(entry.getValue());
        }
    }
    get(index) {
        for (let i = 0; i < __classPrivateFieldGet(this, _mLength); i++) {
            if (index == i)
                return __classPrivateFieldGet(this, _mValues_1)[i];
        }
        return null;
    }
    set(index, value) {
        // if (index > this.#mLength || index < this.#mLength)
        //     throw new IllegalStateException("");
        for (let i = 0; i < __classPrivateFieldGet(this, _mLength); i++)
            if (index == i) {
                __classPrivateFieldGet(this, _mValues_1)[i] = value;
                return;
            }
    }
    indexOf(value) {
        for (let i = 0; i < __classPrivateFieldGet(this, _mLength); i++) {
            let v = value;
            if (v instanceof Object && "equals" in v) {
                if (v.equals(__classPrivateFieldGet(this, _mValues_1)[i]))
                    return i;
            }
            else {
                if (__classPrivateFieldGet(this, _mValues_1)[i] == value)
                    return i;
            }
        }
        return -1;
    }
    contains(value) {
        return this.indexOf(value) >= 0;
    }
    containsInstanceOf(objectName, forAll) {
        if (objectName == null)
            return false;
        if (this.size() > 0) {
            let isFind = false;
            for (let entry of this.entries()) {
                if (entry.getValue().constructor.name == objectName) {
                    if (!forAll)
                        return true;
                    isFind = true;
                }
            }
            return isFind;
        }
        return false;
    }
    containsOnlyInstanceOf(objectName) {
        if (objectName == null)
            return false;
        if (this.size() > 0) {
            let quantity = 0;
            for (let entry of this.entries()) {
                if (entry.getValue().constructor.name == objectName)
                    quantity++;
            }
            return quantity == this.size();
        }
        return false;
    }
    remove(index) {
        let otherValues = [];
        for (let i = 0, v = 0; i < __classPrivateFieldGet(this, _mLength); i++) {
            if (index == i)
                continue;
            otherValues[v++] = __classPrivateFieldGet(this, _mValues_1)[i];
        }
        __classPrivateFieldSet(this, _mValues_1, otherValues);
        this.ensureDecrementSize(1);
        otherValues = null;
    }
    removeQuantity(start, count) {
        for (let i = 0; i < count; i++) {
            for (let e = 0; e < __classPrivateFieldGet(this, _mLength); e++) {
                if (e == start) {
                    this.remove(e);
                    return;
                }
            }
        }
    }
    entries() {
        return new EntryIterable(__classPrivateFieldGet(this, _mValues_1), __classPrivateFieldGet(this, _mLength));
    }
    join(separator) {
        let builder = new StringBuilder_js_1.StringBuilder();
        for (let entry of this.entries()) {
            builder.append(entry.getValue());
            if (!Utils_js_1.UString.isEmpty(separator))
                builder.append(separator);
        }
        return builder.toString();
    }
    clear() {
        for (let i = 0; i < __classPrivateFieldGet(this, _mLength); i++)
            __classPrivateFieldGet(this, _mValues_1)[i] = null;
        __classPrivateFieldSet(this, _mLength, 0);
        __classPrivateFieldSet(this, _mValues_1, []);
    }
    clearMemory() {
        __classPrivateFieldGet(this, _mValues_1).length = 0;
        __classPrivateFieldSet(this, _mLength, 0);
    }
    isEmpty() {
        return __classPrivateFieldGet(this, _mLength) == 0;
    }
    size() {
        return __classPrivateFieldGet(this, _mLength);
    }
    toArray() {
        return __classPrivateFieldGet(this, _mValues_1);
    }
    toString() {
        let builder = new StringBuilder_js_1.StringBuilder();
        builder.append("[");
        for (let entry of this.entries()) {
            builder.append(entry.getValue())
                .append((entry.isLastData() ? "" : ", "));
        }
        builder.append("]");
        return builder.toString();
    }
    clone() {
        let list = new ArrayList();
        if (__classPrivateFieldGet(this, _mLength) > 0)
            list.addAll(this);
        return list;
    }
    sort(c) {
        let a = this.toArray();
        Arrays_js_1.Arrays.sort(a, 0, a.length, c);
        for (let i = 0; i < __classPrivateFieldGet(this, _mLength); i++)
            this.set(i, a[i]);
    }
    filter(filter) {
        let list = new ArrayList();
        for (let i = 0; i < __classPrivateFieldGet(this, _mLength); i++) {
            if (filter.accept(__classPrivateFieldGet(this, _mValues_1)[i]))
                list.add(__classPrivateFieldGet(this, _mValues_1)[i]);
        }
        return list;
    }
    /**
     * Ensures the incrementation of the size to update the current size of the array
     *
     * @param value incremented value
     * @type {void}
     * @since 1.0
     */
    ensureIncrementSize(value) {
        __classPrivateFieldSet(this, _mLength, __classPrivateFieldGet(this, _mLength) + value);
    }
    /**
     * Ensures the decrementation of the size to update the current size of the array
     *
     * @param value Decremented value
     * @type {void}
     * @since 1.0
     */
    ensureDecrementSize(value) {
        __classPrivateFieldSet(this, _mLength, __classPrivateFieldGet(this, _mLength) - value);
    }
}
exports.ArrayList = ArrayList;
_mValues_1 = new WeakMap(), _mLength = new WeakMap();
//# sourceMappingURL=ArrayList.js.map